module shader.litshaderlighting;

import render.render;
import scene.scene;
import scene.ray;
import scene.intersection;
import shader.abstractshader;
import shader.light;
import shader.lightsources;
import std.math;
import utils.color;
import utils.vector3;

const float SHADE_EPSILON = 1e-8f;

class LitShaderLighting: AbstractShader {
    LightSources mLights;

    const bool attLinear = false;

    public void getColor(inout RenderContext context) {
        Vector3f x = context.rinters.hitpoint;
        Vector3f n = context.rinters.normal;
        Ray secRay;
        Intersection ints;
        if (mLights) {
            foreach (inout Light l; mLights.lights) {
                float r = (l.p-x).length();             //light distance
                Vector3f wi = (l.p-x).normal();         //light direction
                float fDot = wi*n;
                if (fDot > 0) {
                    //offset origin point a little into direction of surface
                    //normal to avoid self-intersection
                    secRay = Ray(x+n*SHADE_EPSILON,wi,r);
                    bool v = !context.scene.intersectShadowRay(secRay);
                    if (v) {
                        r /= 100.0f;
                        float att = 1.0f;
                        if (attLinear)
                            att += r;
                        else
                            att += r*r;
                        //context.color += l.col*(1.0f/att)*context.material.value(context,wi)*fDot;
                        context.addDirectionalLight(l.col*(1.0f/att), wi);
                    }
                }
            }
        }
    }

    public char[] toString() {
        return "Lights/Shadows";
    }

    public LightSources lights() {
        return mLights;
    }
    public void lights(LightSources l) {
        mLights = l;
    }
}
